import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { ETheme } from "types/index.d";
import { Color } from "tvision-color";
import { CHART_COLORS, defaultColor } from "@/configs/color";
import { generateColorMap, insertThemeStylesheet } from "@/utils/color";
import { RootState } from "../store";
import { version } from "../../../package.json";

const namespace = "global";

export enum ELayout {
  side = 1,
  top,
  mix,
  fullPage,
}

export interface IGlobalState {
  // 是否正在加载
  loading: boolean;
  // 菜单是否闭合
  collapsed: boolean;
  // 是否显示设置
  setting: boolean;
  // 版本
  version: string;
  // 主题色
  color: string;
  // 主题 light/dark
  theme: ETheme;
  // 是否开启跟随系统主题
  systemTheme: boolean;
  // 布局
  layout: ELayout;
  // 是否全屏
  isFullPage: boolean;
  // 是否显示头部
  showHeader: boolean;
  // 是否显示面包屑
  showBreadcrumbs: boolean;
  // 是否显示底部
  showFooter: boolean;
  // 图表颜色
  chartColors: Record<string, string>;
}

const defaultTheme = (localStorage.getItem("HIST-theme") ||
  "light") as keyof typeof ETheme;
const color = localStorage.getItem("HIST-Color") || defaultColor[0];
const initialState: IGlobalState = {
  loading: true,
  collapsed: window.innerWidth < 1000, // 宽度小于1000 菜单闭合
  setting: false,
  version,
  theme: ETheme[defaultTheme],
  systemTheme: false,
  layout: ELayout.side,
  isFullPage: false,
  // 当前主题色
  color,
  showHeader: true,
  showBreadcrumbs: true,
  showFooter: true,
  chartColors: CHART_COLORS[defaultTheme],
};

// 创建带有命名空间的 reducer
const globalSlice = createSlice({
  name: namespace,
  initialState,
  reducers: {
    toggleMenu(state, action) {
      if (action.payload === null) {
        state.collapsed = !state.collapsed;
      } else {
        state.collapsed = !!action.payload;
      }
    },
    toggleSetting(state) {
      state.setting = !state.setting;
    },
    toggleShowHeader(state) {
      state.showHeader = !state.showHeader;
    },
    toggleShowBreadcrumbs(state) {
      state.showBreadcrumbs = !state.showBreadcrumbs;
    },
    toggleShowFooter(state) {
      state.showFooter = !state.showFooter;
    },
    // 切换主题
    switchTheme(state, action: PayloadAction<ETheme>) {
      const finalTheme = action?.payload;
      // 切换 chart 颜色
      state.chartColors = CHART_COLORS[finalTheme];
      // 切换主题颜色
      state.theme = finalTheme;
      // 关闭跟随系统
      state.systemTheme = false;
      document.documentElement.setAttribute("theme-mode", finalTheme);
      // 保存主题到本地存储
      localStorage.setItem("HIST-theme", finalTheme);
    },
    // 跟随系统主题
    openSystemTheme(state) {
      const media = window.matchMedia("(prefers-color-scheme:dark)");
      const finalTheme = media.matches ? ETheme.dark : ETheme.light;
      state.chartColors = CHART_COLORS[finalTheme];
      // 切换主题颜色
      state.theme = finalTheme;
      state.systemTheme = true;
      document.documentElement.setAttribute("theme-mode", finalTheme);
      // 保存主题到本地存储
      localStorage.setItem("HIST-theme", finalTheme);
    },
    // 切换主题色
    switchColor(state, action) {
      if (action?.payload) {
        state.color = action?.payload;
        const mode = state.theme;
        const hex = action?.payload;
        const { colors: newPalette, primary: brandColorIndex } =
          Color.getColorGradations({
            colors: [hex],
            step: 10,
            remainInput: false, // 是否保留输入 不保留会矫正不合适的主题色
          })[0];
        const newColorMap = generateColorMap(
          hex,
          newPalette,
          mode,
          brandColorIndex
        );
        insertThemeStylesheet(hex, newColorMap, mode);
        document.documentElement.setAttribute("theme-color", hex || "");
        // 保存主题色到本地存储
        localStorage.setItem("HIST-Color", hex);
      }
    },
    switchLayout(state, action) {
      if (action?.payload) {
        state.layout = action?.payload;
      }
    },
    switchFullPage(state, action) {
      state.isFullPage = !!action?.payload;
    },
  },
});

export const selectGlobal = (state: RootState) => state.global;

export const {
  toggleMenu,
  toggleSetting,
  toggleShowHeader,
  toggleShowBreadcrumbs,
  toggleShowFooter,
  switchTheme,
  switchColor,
  switchLayout,
  switchFullPage,
  openSystemTheme,
} = globalSlice.actions;

export default globalSlice.reducer;
